package com.ruoyi.framework.web.service;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.DeviceInfo;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 登录会话管理器
 * 提供统一的登录用户信息和设备信息存储管理
 *
 * @author ruoyi
 */
@Slf4j
@Component
public class LoginSessionManager {

    /**
     * 将LoginUser信息存储到会话中，支持多设备登录时保持各自的设备信息
     *
     * @param loginUser  登录用户信息
     * @param tokenValue token值
     */
    public void storeLoginUserToSession(LoginUser loginUser, String tokenValue) {
        try {
            SaSession session = StpUtil.getSession();
            
            // 创建只包含基本用户信息的LoginUser（不包含设备信息）
            LoginUser baseLoginUser = createBaseLoginUser(loginUser);
            
            // 存储基本用户信息到默认key（用于权限验证等通用操作）
            session.set(Constants.LOGIN_USER_KEY, baseLoginUser);
            
            // 创建并存储设备特定信息
            DeviceInfo deviceInfo = DeviceInfo.fromLoginUser(loginUser);
            if (deviceInfo != null) {
                String deviceKey = buildDeviceKey(tokenValue);
                session.set(deviceKey, deviceInfo);
            }
            
        } catch (Exception e) {
            log.warn("存储登录用户信息到会话失败，使用降级方案", e);
            LoginUser baseLoginUser = createBaseLoginUser(loginUser);
            StpUtil.getSession().set(Constants.LOGIN_USER_KEY, baseLoginUser);
        }
    }

    /**
     * 创建只包含基本用户信息的LoginUser对象（不包含设备信息）
     *
     * @param loginUser 完整的登录用户信息
     * @return 基本用户信息
     */
    public LoginUser createBaseLoginUser(LoginUser loginUser) {
        LoginUser baseLoginUser = new LoginUser();
        baseLoginUser.setUserId(loginUser.getUserId());
        baseLoginUser.setDeptId(loginUser.getDeptId());
        baseLoginUser.setUser(loginUser.getUser());
        baseLoginUser.setPermissions(loginUser.getPermissions());
        // 不设置设备相关信息：token, loginTime, ipaddr, loginLocation, browser, os
        return baseLoginUser;
    }

    /**
     * 构建设备信息存储key
     *
     * @param tokenValue token值
     * @return 设备信息key
     */
    public String buildDeviceKey(String tokenValue) {
        return Constants.LOGIN_USER_KEY + ":device:" + tokenValue;
    }

    /**
     * 清理指定token的设备信息
     *
     * @param tokenValue token值
     */
    public void cleanupTokenDeviceInfo(String tokenValue) {
        if (StringUtils.isEmpty(tokenValue)) {
            return;
        }
        
        try {
            Object loginId = StpUtil.getLoginIdByToken(tokenValue);
            if (loginId != null) {
                String deviceKey = buildDeviceKey(tokenValue);
                StpUtil.getSessionByLoginId(loginId).delete(deviceKey);
            }
        } catch (Exception e) {
            log.warn("清理设备信息异常: token={}, error={}", tokenValue, e.getMessage());
        }
    }
}
